package com.sleepingcat.ft_jetpack.coroutine

import androidx.lifecycle.lifecycleScope
import com.cat.android.lib_base.base.RouterFragment
import com.cat.android.lib_base.ext.logD
import com.cat.android.lib_ui.ext.onClick
import com.cat.android.plugin_navigation_runtime.NavDestination
import com.sleepingcat.ft_jetpack.databinding.FragmentCoroutineBaseBinding
import com.sleepingcat.lib_common.const.Routes
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import kotlin.coroutines.resume

@NavDestination(type = NavDestination.NavType.Fragment, route = Routes.Jetpack.COROUTINE_BASE)
class CoroutineBaseFragment : RouterFragment<FragmentCoroutineBaseBinding>() {
    private val tag = "CoroutineBaseFragment"

    override fun initView() {
        super.initView()
        binding.apply {
            btn1.onClick {
                demo1()
            }
            btn2.onClick {
                demo2()
            }
            btn3.onClick {
                demo3()
            }
            btn4.onClick {
                demo4()
            }
        }
    }

    // 单个使用
    private fun demo1() {
        suspend fun getName(): String {
            delay(2000)
            return "cat"
        }
        lifecycleScope.launch {
            val start = System.currentTimeMillis()
            "开启一个协程".logD(tag)
            val name = getName()
            val end = System.currentTimeMillis()
            "获取到name数据，等于${name}，耗时：${takeUpTime(start, end)}秒".logD(tag)
        }
    }

    // 多个串行使用
    private fun demo2() {
        suspend fun getName(): String {
            delay(2000)
            return "cat"
        }

        suspend fun getAge(): Int {
            delay(1000)
            return 20
        }
        lifecycleScope.launch {
            val start = System.currentTimeMillis()
            "开启一个协程".logD(tag)
            val name = getName()
            val end = System.currentTimeMillis()
            "获取到name数据，等于${name}，耗时：${takeUpTime(start, end)}".logD(tag)
            val age = getAge()
            val end1 = System.currentTimeMillis()
            "获取到age数据，等于${age}，耗时：${takeUpTime(end, end1)}".logD(tag)
        }
    }

    // 切线程
    private fun demo3() {
        lifecycleScope.launch(Dispatchers.IO) {
            "开启一个协程，当前线程是：${Thread.currentThread().name}".logD(tag)
            withContext(Dispatchers.Main) {
                "切换，当前线程是：${Thread.currentThread().name}".logD(tag)
            }
            "结束协程，当前线程是：${Thread.currentThread().name}".logD(tag)
        }
    }

    // 回调变协程
    private fun demo4() {
        suspend fun getName() = suspendCancellableCoroutine<String> {
            val callback = object : TestCallback {
                override fun onGetName(name: String) {
                    it.resume(name)
                }
            }
            callback.onGetName("cat")
        }
        lifecycleScope.launch {
            delay(2000)
            val name = getName()
            "获取到name=$name".logD(tag)
        }
    }

    interface TestCallback {
        fun onGetName(name: String)
    }

    private fun takeUpTime(start: Long, end: Long): Int {
        return ((end - start) / 1000).toInt()
    }
}